use hypers::prelude::*;
use hypers::tracing::info;

static INDEX_HTML: &str = r#"<!DOCTYPE html>
<html>
    <head>
        <title>Upload files</title>
    </head>
    <body>
        <h1>Upload files</h1>
        <form action="/uploads" method="post" enctype="multipart/form-data">
            <input type="file" name="files" multiple/>
            <input type="submit" value="upload" />
        </form>
    </body>
</html>
"#;

// http://127.0.0.1:7878/uploads
pub async fn uploads(mut req: Request) -> Result<String, Error> {
    let save_path = "upload_files/temp";
    if let Ok(files) = req.files("files").await {
        std::fs::create_dir_all(save_path)?;
        let mut msgs = Vec::with_capacity(files.len());
        for file in files {
            let dest = format!("{}/{}", save_path, file.name.as_deref().unwrap());
            if let Err(e) = std::fs::copy(&file.path, std::path::Path::new(&dest)) {
                return Ok(format!("file not found in request: {e}"));
            } else {
                msgs.push(dest);
            }
        }
        Ok(format!("Files uploaded:\n\n{}", msgs.join("\n")))
    } else {
        Err("Files not resolved from current request".into())
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    tracing_subscriber::fmt().init();
    let mut root = Router::default();
    root.get("/upload", |_| async {
        Text::Html(INDEX_HTML) // http://127.0.0.1:7878/upload
    })
    .post("/uploads", uploads);
    info!("root = {:#?}", root);
    let listener = hypers::TcpListener::bind("127.0.0.1:7878").await?;
    hypers::listen(root, listener).await
}
